/********************************************************************************
 * SHAMATA 32-bit Optimized Code Header File
 * October 2008

 # ShamataOptimized_32bit.h
 # Algorithm Name: SHAMATA
 # Principal Submitter: Orhun KARA
 *******************************************************************************/

/* The followings are for multiplication over GF(2^8) with the primitive polynomial (x^8 + x^7 + x^5 + x + 1) for AES block */
#define R_f8 0x1b                                                // Primitive polynomial remainder
#define MULT8_BY_2(x) (((x<<1)&0xff) ^ ((x>>7) == 1 ? R_f8 : 0)) // Multiplication by x over GF(2^8)
#define MULT8_BY_3(x) (MULT8_BY_2(x) ^ x)                        // Multiplication by (x + 1) over GF(2^8)

typedef unsigned char BitSequence;
typedef unsigned long long DataLength;
typedef enum {SUCCESS = 0, FAIL = 1, BAD_HASHBITLEN = 2} HashReturn;
typedef enum {MESSAGEBLOCK = 0, PARITYBLOCK = 1} BlockType;

// Data structure
typedef struct {
     unsigned int B[4][4], K[12][4];    // State registers (include chaning value)
	 unsigned int r;                 // Round count of ARF (AES Round Function) for message blocks
	 unsigned int hashbitlen;          // Hash bit length
	 unsigned int remainingdatabitlen; // databitlen%128
	 unsigned int remainingdata[8];    // The last databitlen%128 bits data in the input data of the hash function
	 DataLength databitlen;            // Data bit length
     } hashState;

HashReturn Hash(int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval);
HashReturn Init(hashState *state, int hashbitlen);
HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen);
HashReturn Final(hashState *state, BitSequence *hashval);


HashReturn Init224(hashState *state, int hashbitlen);
HashReturn Init256(hashState *state, int hashbitlen);
HashReturn Init384(hashState *state, int hashbitlen);
HashReturn Init512(hashState *state, int hashbitlen);

HashReturn Update224_256(hashState *state, const BitSequence *data, DataLength databitlen);
HashReturn Update384_512(hashState *state, const BitSequence *data, DataLength databitlen);

HashReturn Final224_256(hashState *state, BitSequence *hashval);
HashReturn Final384_512(hashState *state, BitSequence *hashval);

HashReturn FinalUpdate224_256(hashState *state, const BitSequence *data);
HashReturn FinalUpdate384_512(hashState *state, const BitSequence *data);

HashReturn ProduceOutput(hashState *state, BitSequence *hashval);